<template>
	<el-descriptions title="个人信息" direction="vertical" border style="margin-top: 20px">
		<el-descriptions-item :rowspan="2" :width="140" label="头像" align="center">
			<div class="avatar-box" @click="dialogVisible = true">
				<el-avatar :size="200" :src="avatar" />
				<!-- 遮罩层：默认隐藏，悬浮显示 -->
				<div class="avatar-overlay">
					<div class="avatar-btn">
						<i-ep-plus />
					</div>
				</div>
			</div>
		</el-descriptions-item>
		<el-descriptions-item label="用户名">{{ userInfo.username }}</el-descriptions-item>
		<el-descriptions-item label="昵称">{{ userInfo.nickname }}</el-descriptions-item>
		<el-descriptions-item label="状态">
			<el-tag v-if="userInfo.active">正常</el-tag>
			<el-tag v-else>停用</el-tag>
		</el-descriptions-item>
		<el-descriptions-item label="Remarks">
			<el-tag>School</el-tag>
		</el-descriptions-item>
		<el-descriptions-item label="所属角色">
			No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province
		</el-descriptions-item>
	</el-descriptions>

	<el-dialog v-model="dialogVisible" title="上传头像" width="800" :before-close="handleCancel">
		<el-row>
			<el-col :xs="24" :md="12" class="h-350px">
				<VueCropper
					ref="cropper"
					:info="false"
					:img="options.img"
					:autoCrop="options.autoCrop"
					:autoCropWidth="options.autoCropWidth"
					:autoCropHeight="options.autoCropHeight"
					:fixedBox="options.fixedBox"
					outputType="png"
					@realTime="realTime"
				/>
			</el-col>

			<el-col :xs="24" :md="12" class="upload-preview h-350px">
				<div class="preview">
					<img v-if="previews" :src="previews.url" :style="previews.img" />
				</div>
			</el-col>
		</el-row>

		<el-row align="middle" class="m-t-10px">
			<el-col :lg="{ span: 1, offset: 1 }" :md="2">
				<ElUpload
					v-model:file-list="fileList"
					multiple
					:limit="1"
					:on-change="onChange"
					:auto-upload="false"
					:show-file-list="false"
				>
					<el-button type="primary">上传</el-button>
				</ElUpload>
			</el-col>
			<el-col :lg="{ span: 1, offset: 1 }" :md="2">
				<ElButton type="default" :icon="ZoomOut" @click="changeScale(1)"> </ElButton>
			</el-col>
			<el-col :lg="{ span: 1, offset: 1 }" :md="2">
				<ElButton type="default" :icon="RefreshRight" @click="rotateLeft"></ElButton>
			</el-col>
			<el-col :lg="{ span: 1, offset: 1 }" :md="2">
				<ElButton type="default" :icon="RefreshLeft" @click="rotateRight"></ElButton>
			</el-col>
			<el-col :lg="{ span: 1, offset: 1 }" :md="2">
				<ElButton :icon="ZoomIn" type="default" @click="changeScale(-1)"> </ElButton>
			</el-col>
		</el-row>
		<template #footer>
			<div class="dialog-footer">
				<el-button @click="handleCancel">取消</el-button>
				<el-button type="primary" @click="handleSubmit">确认</el-button>
			</div>
		</template>
	</el-dialog>
</template>

<script setup lang="ts">
import type { UploadUserFile } from "element-plus";
import { uploadFile } from "@/api/index";
import { updateUser, getUserInfo } from "@/api/user";
import { useUserStore } from "@/store";
import "vue-cropper/dist/index.css";
import { VueCropper } from "vue-cropper";
import { RefreshRight, RefreshLeft, ZoomIn, ZoomOut } from "@element-plus/icons-vue";

const userStore = useUserStore();
const fileList = ref<UploadUserFile[]>([]);

/**获取用户头像地址 */
const avatar = computed(() => userStore.avatar);

/**弹框 */
const dialogVisible = ref(false);

//vue-cropper
const previews = ref();
const cropper = ref();
const fileName = ref();
const options = reactive({
	img: "", //裁剪图片的地址
	autoCrop: true, //是否默认生成截图框
	autoCropWidth: 200, //默认生成截图框宽度
	autoCropHeight: 200, //默认生成截图框高度
	fixedBox: true, //是否固定截图框大小 不允许改变
	previewsCircle: false, //预览图是否是原圆形
	centerBox: true, //截图框是否被限制在图片里面
	fixedNumber: [1, 1], // 截图框的宽高比例
	title: "修改图片",
});

/**
 * 文件变化处理函数
 * @param file 文件对象
 */
const onChange = (file: any) => {
	if (file) {
		fileList.value[0] = file;
		const reader = new FileReader();
		reader.readAsDataURL(file.raw);
		reader.onload = function (e) {
			options.img = e.target!.result as string;
			fileName.value = file.name;
		};
	}
};

/**
 * @Description: 计算原图与裁剪框显示的图片的比例,裁剪框的大小(需要传入原图的文件！！！, 裁剪弹框的高度)
 * 实现的功能：
 * 1.如果没有传截图框的比例，那么默认是1:1,那一边短那一边被当成截图框的长度。
 * 2.传入截图框比例，有六种情况，处理原则为截图框比例不会改变的情况下截取原图一边。
 * 三个重要核心：
 * 1.原图与裁剪弹框的比例。
 * 2.原图宽高比例。
 * 3.截图框宽高比例。
 */

/**移动框的事件 */
const realTime = (data: any) => {
	previews.value = data;
};

/**图片缩放 */
function changeScale(num: number) {
	num = num || 1;
	cropper.value.changeScale(num);
}
/**向左旋转 */
function rotateLeft() {
	cropper.value.rotateLeft();
}
/**向右旋转 */
function rotateRight() {
	cropper.value.rotateRight();
}

/**取消提交按钮 */
const handleCancel = () => {
	dialogVisible.value = false;

	//清空裁剪框数据
	options.img = "";
	previews.value = {};
	fileList.value = [];
	fileName.value = "";
};

/**提交事件 */
async function handleSubmit() {
	cropper.value.getCropData(async (data: any) => {
		//拿到裁剪后的原始数据
		const file = dataURLtoFile(data, fileName.value);
		const fileData = new FormData();
		fileData.append("file", file);
		const result = await uploadFile(fileData);
		const avatar = result.data.url;
		const res = await updateUser({ avatar, id: userStore.id });
		if (res.code === 200) {
			userStore.avatar = res.data.avatar;
			ElMessage.success("更新成功！");
		}
		//调用接口--传递给后台--从后台再读取新的图片链接并赋值即可
		// const result = await 后台接口({ file });
		dialogVisible.value = false;
	});
}

/**base 64 转成二进制文件流 */
const dataURLtoFile = (dataurl: any, filename: any) => {
	let arr = dataurl.split(","),
		mime = arr[0].match(/:(.*?);/)[1],
		bstr = atob(arr[1]),
		n = bstr.length,
		u8arr = new Uint8Array(n);
	while (n--) {
		u8arr[n] = bstr.charCodeAt(n);
	}
	return new File([u8arr], filename, { type: mime });
};

const userInfo = reactive({
	username: "",
	nickname: "",
	avatar: "",
	active: "",
});

/**获取用户信息 */
const getUserInfoData = async () => {
	const res = await getUserInfo();
	if (res.code === 200) {
		Object.assign(userInfo, res.data);
		console.log(userInfo);
	}
};
onMounted(() => {
	getUserInfoData();
});
</script>

<style scoped lang="scss">
.avatar-box {
	position: relative;
	display: inline-block;
	cursor: pointer;
	.el-avatar {
		display: block;
	}
	.avatar-overlay {
		position: absolute;
		top: 0;
		left: 0;
		display: flex;
		align-items: center;
		justify-content: center;
		width: 100%;
		height: 100%;
		pointer-events: none; // 避免遮罩层挡住点击
		background-color: rgb(0 0 0 / 40%); // 半透明黑色遮罩
		border-radius: 50%;
		opacity: 0;
		transition: opacity 0.3s ease;
	}
	.avatar-btn {
		font-size: 24px;
		color: #ffffff;
	}
	&:hover .avatar-overlay {
		pointer-events: auto;
		opacity: 1;
	}
}
.upload-preview {
	position: relative;
	.preview {
		position: absolute;
		top: 50%;
		left: 50%;
		width: 200px;
		height: 200px;
		overflow: hidden;
		border-radius: 50%;
		box-shadow: 0 0 4px #cccccc;
		transform: translate(-50%, -50%);
	}
}
</style>
